<?php

class offerActions extends sfActions {

  public function executePurchase(sfWebRequest $request) {
    if(sfConfig::get('sf_environment') == 'prod' && (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == '')) {
      $redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
      header('Location: ' . $redirect);
    }
    
    if ($request->isMethod('post') && !$request->hasParameter('purchase')) {
      $this->getUser()->setAttribute('quantity', $request->getParameter('quantity'));
    }
    if (!$request->getParameter('quantity') && !$this->getUser()->getAttribute('quantity')) {
      $this->redirect('@home');
    }
    
    $offerId = $request->getParameter('id');
    $offerId = explode('-', $offerId);
    $offer = isset($offerId[0]) ? OFFERTable::getInstance()->find($offerId[0]) : null;

    $this->forward404If(!($offer instanceof OFFER) || (($offer instanceof OFFER) && implode('-', array_slice($offerId, 1)) != (StringUtil::slugify($offer->getMOVIE()->getTitle()))));

    $movie = $offer->getMOVIE();
    $cinema = $offer->getCINEMA();
    $merchant = $cinema->getMERCHANT();

    $this->forward404If(($movie->getStatus() != Constants::STATUS_ACTIVE) || ($cinema->getStatus() != Constants::STATUS_ACTIVE) || ($merchant->getStatus() != Constants::STATUS_ACTIVE));

    $this->form = new PurchaseForm($offer->getSeatsAvailableCount());
    if ($request->getParameter('q') == 1) {
      $ticketId = $this->getUser()->getAttribute(Constants::SESSION_BOOKED_TICKET_ID);
      $ticket = TICKETTable::getInstance()->find($ticketId);
      if ($ticket instanceof TICKET) {
        $this->form->populateData($ticket);
        $this->getUser()->getAttributeHolder()->remove(Constants::SESSION_BOOKED_TICKET_ID);
      }
    }

    $errorCollector = array();

    if ($request->isMethod('post') && $request->hasParameter('purchase')) {
      $formData = $request->getParameter(PurchaseForm::FORM_NAME);
      $this->form->bind($formData);

      try {
        if ($this->form->isValid()) {
          $ticket = new TICKET();
          $ticket->setOfferId($offer->getId());
          if ($this->getUser()->isAuthenticated()) {
            $ticket->setUserId($this->getUser()->getAttribute(Constants::SESSION_USER_ID));
          }
          $ticket->setQuantity($this->getUser()->getAttribute('quantity'));
          $ticket->setEmail($formData[PurchaseForm::FIELD_EMAIL]);
          $ticket->setPrice($offer->getTicketPrice());
          $ticket->setBookingFree($merchant->getBookingFee());
          $ticket->setStatus(Constants::STATUS_PAYMENT_PENDING);
          $ticket->save();

          $receiptId = $offer->getCode() . '-' . str_pad(rand(0, 999), 3, '0', STR_PAD_LEFT) . '-' . str_pad($ticket->getId(), 5, '0', STR_PAD_LEFT);

          $xml = '<ewaygateway>
                    <ewayCustomerID>' . sfConfig::get('app_eway_customer_id') . '</ewayCustomerID> 
                    <ewayTotalAmount>' . ((($offer->getTicketPrice()*$this->getUser()->getAttribute('quantity')) + ($merchant->getBookingFee()*$this->getUser()->getAttribute('quantity'))) * 100) . '</ewayTotalAmount> 
                    <ewayCustomerFirstName></ewayCustomerFirstName> 
                    <ewayCustomerLastName></ewayCustomerLastName> 
                    <ewayCustomerEmail>' . $formData[PurchaseForm::FIELD_EMAIL] . '</ewayCustomerEmail> 
                    <ewayCustomerAddress></ewayCustomerAddress> 
                    <ewayCustomerPostcode></ewayCustomerPostcode> 
                    <ewayCustomerInvoiceDescription>' . $offer->getCode() . ' - ' . $offer->getMOVIE()->getTitle() . '</ewayCustomerInvoiceDescription> 
                    <ewayCustomerInvoiceRef>' . $receiptId . '</ewayCustomerInvoiceRef> 
                    <ewayCardHoldersName>' . $formData[PurchaseForm::FIELD_CARD_NAME] . '</ewayCardHoldersName> 
                    <ewayCardNumber>' . $formData[PurchaseForm::FIELD_CARD_NUMBER] . '</ewayCardNumber> 
                    <ewayCardExpiryMonth>' . $formData[PurchaseForm::FIELD_CARD_DATE]['month'] . '</ewayCardExpiryMonth> 
                    <ewayCardExpiryYear>' . $formData[PurchaseForm::FIELD_CARD_DATE]['year'] . '</ewayCardExpiryYear> 
                    <ewayTrxnNumber>' . $ticket->getId() . '</ewayTrxnNumber> 
                    <ewayOption1>' . (isset($formData[PurchaseForm::FIELD_BECOME_MEMBER]) ? 1 : 0) . '</ewayOption1> 
                    <ewayOption2>' . $receiptId . '</ewayOption2> 
                    <ewayOption3></ewayOption3> 
                    <ewayCVN>' . $formData[PurchaseForm::FIELD_CARD_CVN] . '</ewayCVN>
                  </ewaygateway>';
          
          $monviaHttpClient = new MonviaHttpClient();
          $headers = array(
              'Content-Type: text/xml; charset=utf-8',
              'Content-Length: ' . strlen($xml)
          );
          
          if (sfConfig::get('app_eway_is_live') === true) {
            $url = 'https://www.eway.com.au/gateway_cvn/xmlpayment.asp';
          } else {
            $url = 'https://www.eway.com.au/gateway_cvn/xmltest/testpage.asp';
          }
          
          $monviaHttpClient->post($url, $xml, $headers);
          if ($monviaHttpClient->isResponseOk()) {
            $response = $monviaHttpClient->getResponseBody(true);
            $xml = simplexml_load_string($response);
            if ($xml !== false) {
              if ($xml !== false && isset($xml->ewayTrxnStatus)) {
                $returnFields = array('ewayTrxnStatus', 'ewayTrxnNumber', 'ewayTrxnReference', 'ewayAuthCode', 'ewayTrxnOption1', 'ewayTrxnOption2', 'ewayTrxnOption3', 'ewayReturnAmount', 'ewayTrxnError');
                $data = array();
                foreach ($returnFields as $returnField) {
                  $data[$returnField] = (string) $xml->$returnField;
                }
                $data['paymentDate'] = time();
                $this->getUser()->setAttribute('paymentData', base64_encode(serialize($data)));
                $this->redirect('@purchase_complete?id=' . $ticket->getId());
              }
            }
          }
          unset($monviaHttpClient);
        }
      } catch (Exception $e) {
        $errorCollector[] = LangUtil::getText('error_save_failed');
      }
    }

    $this->errorCollector = $errorCollector;
    $this->offer = $offer;
    $this->movie = $movie;
    $this->cinema = $cinema;
    $this->merchant = $merchant;
    $this->quantity = $this->getUser()->getAttribute('quantity');
  }

  public function executePurchaseComplete(sfWebRequest $request) {
    $data = unserialize(base64_decode($this->getUser()->getAttribute('paymentData')));
    
    if (is_array($data)) {
      $ticketId = $data['ewayTrxnReference'];
      $this->forward404Unless($ticketId == $request->getParameter('id'));
      $ticket = TICKETTable::getInstance()->find($ticketId);
      $this->forward404Unless($ticket instanceof TICKET);
      $this->getUser()->setAttribute(Constants::SESSION_BOOKED_TICKET_ID, $ticket->getId());
      $offer = $ticket->getOFFER();
      $movie = $offer->getMOVIE();
      $cinema = $offer->getCINEMA();
      
      $ticket->setPaymentDate(date(Constants::DATE_TIME_MYSQL_DB, $data['paymentDate']));
      $ticket->setPaypalDataDump(serialize($data));
      
      $trans = SystemUtil::beginDoctrineTransaction();
      try {
        if ($data['ewayTrxnStatus'] == 'True') {
          $ticket->setTxnId($data['ewayTrxnNumber']);
          $ticket->setReceiptId($data['ewayTrxnOption2']);
          $ticket->setStatus(Constants::STATUS_PAYMENT_SUCCESS);
          
          $email = new EMAIL();
          $email->setEmailTo($ticket->getEmail());
          $email->setSubject('Order Confirmation');
          $email->setMessage($this->_getReceiptDetails($ticket, $movie, $cinema, $offer));
          $email->setTemplateFile('orderConfirm');
          $email->setContentType(emailTask::CONTENT_TYPE_HTML);
          $email->save();
          
          $offer->setSeatsAvailableCount($offer->getSeatsAvailableCount() - $ticket->getQuantity());
          $offer->save();

          if ($offer->getSeatsAvailableCount() < 0) {
            SystemUtil::sendAlertEmail('Seats availability error', 'Not enough seats to allocate for ' . $ticket->getId() . '. Only ' . $offer->getSeatsAvailableCount() . ' seats available!');
          }
          
          if ($data['ewayTrxnOption1'] == '1') {
            $this->signup = true;
          }
          
          $this->receiptInfo = $this->_getReceiptDetails($ticket, $movie, $cinema, $offer);
        } else {
          $ticket->setStatus(Constants::STATUS_PAYMENT_FAIL);
        }
        $ticket->save();
        SystemUtil::commitDoctrineTransaction($trans);
      } catch (Exception $e) {
        SystemUtil::sendAlertEmail('DB Save Error', 'Unable to save payment details for ' . $ticket->getId() . ' because ' . $e->getMessage() . ' ' . print_r($ticket->toArray(), true));
        SystemUtil::rollbackDoctrineTransaction($trans);
      }

      $this->offer = $offer;
      $this->movie = $movie;
      $this->cinema = $cinema;
      $this->ticket = $ticket;
      $this->data = $data;
      $this->getUser()->getAttributeHolder()->remove('paymentData');
    } else {
      $this->redirect('@home');
    }
  }

  private function _getReceiptDetails(TICKET $ticket, MOVIE $movie, CINEMA $cinema, OFFER $offer) {
    return array(
        'ticid' => $ticket->getId(),
        'receiptid' => $ticket->getReceiptId(),
        'txnid' => $ticket->getTxnId(),
        'email' => $ticket->getEmail(),
        'title' => 'Supertain Receipt',
        'movie' => $movie->getTitle(),
        'sessiontime' => $offer->getSessionTimeFormatted(),
        'cinema' => $cinema->getName(),
        'quantity' => $ticket->getQuantity(),
        'price' => $ticket->getTotalPriceFormatted()
    );
  }

  public function executeDownloadReceipt(sfWebRequest $request) {
    $fileName = $request->getParameter('file');
    $fileName = sfConfig::get('sf_data_dir') . '/pdf/' . $fileName . '.pdf';

    header('Content-type: application/pdf');
    header("Content-Disposition: attachment; filename='supertainme-receipt.pdf'");
    readfile($fileName);

    return sfView::NONE;
  }

  public function executePrintReceipt(sfWebRequest $request) {
    
  }

}